--[[
	Project:		TruRP
	Author:			Martin 'Ploo' Pucilowski
	File:			properties.lua
	Date:			02/2010
	Description:	Manages all properties, doors, purchases, rentals, keys and vehicles.
--]]


local entity = FindMetaTable("Entity")




--[[
Retrieves all properties from SQL and places them in a table, indexed by property_id.
--]]
function LoadProperties()
	local query = "SELECT property_id, type, title, cost FROM `properties` WHERE `map` = '" .. game.GetMap() .. "'"
	local result = SQLQuery( query )
	
	for k, v in pairs( result ) do
		local property = TRU.Properties[ tonumber( v.property_id ) ]
		property = {  }
		property.type = tonumber( v.type )
		property.title = v.title
		property.cost = tonumber( v.cost )
	end
end

--[[
Retrieves all doors from SQL and places them in a table, indexed by door_id.
--]]
function LoadDoors()
	local query = "SELECT property_id, door_id, title FROM `doors` WHERE `map` = '" .. game.GetMap() .. "'"
	local result = SQLQuery( query )
	
	for k, v in pairs( result ) do
		local door = TRU.Doors[ tonumber( v.door_id ) ]
		door = {  }
		door.property_id = tonumber( v.property_id )
		door.title = v.title
	end
end

function LoadRentedProperties()
	local query = "SELECT property_id, title, renter, rentedtime, rentedlength FROM `rented_properties` WHERE `map` = '" .. game.GetMap() .. "'"
	local result = SQLQuery( query )
	
	for k, v in pairs( result ) do
		local property = TRU.Properties[ tonumber( v.property_id ) ]
		property = {  }
		property.rentedtitle = v.title
		property.renter = v.renter
		property.rentedtime = tonumber( v.rentedtime )
		property.renterlength = tonumber( v.rentedlength )
	end
end

function LoadRentedDoors()
	local query = "SELECT door_id, title FROM `doors` WHERE `map` = '" .. game.GetMap() .. "'"
	local result = SQLQuery( query )
	
	for k, v in pairs( result ) do
		local door = TRU.Doors[ tonumber( v.door_id ) ]
		door = {  }
		door.rentedtitle = v.title
	end
end

function GetPropertyDoors( property_id )
	local doors = {  }
	
	for _, v in pairs( TRU.Doors ) do
		if v.property_id == property_id then
			table.insert( doors, v )
		end
	end
	
	return doors
end

function GetPropertyData( property_id )
	if not TRU.Properties[ property_id ] then return end
	return TRU.Properties[ property_id ]
end

function GetDoorData( door_id )
	if not TRU.Doors[ door_id ] then return end
	return TRU.Doors[ door_id ]
end

function GetPropertyID( door_id )
	if not ValidDoor( Entity( door_id ) ) then return end
	if not GetDoorData( door_id ) then return end
	return GetDoorData( door_id ).property_id
end



local function InitializeProperties()
	LoadProperties()
	LoadDoors()
	--LoadRentedProperties()
	--LoadRenterDoors()

	PrintTable( TRU.Properties )
	PrintTable( TRU.Doors )

	for _, door in pairs( ents.GetAll() ) do
		if ValidDoor( door ) then
			if TRU.Doors[ door:EntIndex() ] then
				--Property = TRU.Properties[ TRU.Doors[ door:EntIndex() ].property_id ]
				door:Fire("lock", "", 0)
			else
				door:Fire("unlock", "", 0)
			end
			UpdateNWDoorData( door:EntIndex() )
		end
	end
end
hook.Add( "InitPostEntity", "RPInitializeProperties", InitializeProperties )



--[[
Updates networked data of all doors which belong to a certain property
--]]
function UpdateNWPropertyData( property_id )
	local doors = GetPropertyDoors( property_id )
	
	for _, v in pairs( doors ) do
		UpdateNWDoorData( v.door_id )
	end
end

--[[
Updates networked data of a door
--]]
function UpdateNWDoorData( door_id )
	door = Entity( door_id )
	
	if not ValidDoor( door ) then return end
	
	local property_id = GetPropertyID( door_id )
	
	if GetPropertyData( property_id ) then
		print("D")
		local DoorData = TRU.Doors[ door_id ]
		print("Property data found")
		local PropertyData = GetPropertyData( self )
		self:SetNWString( "PropertyTitle", PropertyData.title )
		self:SetNWInt( "PropertyType", PropertyData.type )
		self:SetNWInt( "PropertyCost", PropertyData.cost )
		self:SetNWString( "DoorTitle", DoorData.title )
		self:SetNWInt( "DoorType", DoorData.type )
	end
end









local function PropertyRent( property_id, ply, bought )
	if not ValidProperty( property_id ) then return end
	
	local renter = {
		SteamID = ply:SteamID(),
		Player = ply,
		Name = ply:Name()
	}

	TRU.Properties[ property_id ].renter = renter
	
	UpdateNWPropertyData( property_id )
end

local function PropertyCancelRent( property_id, ply, bought )
	if not ValidProperty( property_id ) then return end
	
	TRU.Properties[ property_id ].renter = nil
	
	UpdateNWPropertyData( property_id )
end

local function PropertyIsRenter( property_id, ply )
	if not ValidProperty( property_id ) then return end
	
	if TRU.Properties[ property_id ].renters[1] == ply then
		return true
	end
	return false
end

local function PropertyCanRent( property_id, ply )
	if not ValidProperty( property_id ) then return end
	
	if not TRU.Properties[ property_id ].renter then
		return true
	end
	return false
end

local function PropertyHasKeys( property_id, ply )
	if not ValidProperty( property_id ) then return end
	
	for k, v in pairs( TRU.Properties[ property_id ].renters ) do
		if v.player == ply then
			return true
		end
	end
	return false
end

function ValidProperty( property_id )
	if TRU.Properties[ property_id ] then return true end
	return false
end

function ValidDoor( door )
	if ValidEntity( door ) and door:IsDoor() then return true end
	return false
end



-- PropertyRent
command.Add("RP_PropertyRent", "prent", function(ply, cmd, args)
	if not TraceDoor( ply ) then return end
	local door = TraceDoor( ply )
	
	local property_id = TRU.Doors[ door:EntIndex() ].property_id
	
	if PropertyCanRent( property_id, ply ) then
		ply:ChatPrint("You now rent this door.")
		PropertyRent( property_id, ply)
	end
end )

-- PropertyCancelRent
command.Add("RP_PropertyCancelRent", "crent", function(ply, cmd, args)
	if not TraceDoor( ply ) then return end
	local door = TraceDoor( ply )
	
	local property_id = TRU.Doors[ door:EntIndex() ].property_id
	
	if PropertyIsRenter( property_id, ply ) then
		ply:ChatPrint("You no longer rent this door.")
		TRU.Properties[ property_id ].renter = nil
	end
end )